package warehouse;



import java.util.LinkedList;
import java.util.List;



/**
 * Item Superclass contains the Item information that would be similar
 * if another item was to be added later in our warehouse
 * @author Apeiranthitis, Grassos, Moschos
 *
 */

public class Item implements Comparable<Item>, Subject{
	//instance  variables
	private String itemID;
	private double price;
	private int quantity;
	

	// list of observers
				private static List<Observer> registeredObservers = new LinkedList<Observer>();
	//some static values we are going to use for data checking
	private static final int MINIMUM_ITEM_ID = 100;
	private static final int MAXIMUM_ITEM_ID = 999;
	private static final double MINIMUM_PRICE = 0.00;
	private static final double MINIMUM_QUANTITY = 0.00;



	/**
	 * Initializes the Item class constructor and catches the NumberFormatException
	 * in case that the price or the quantity is not an arithmetic value
	 * @param id the Id of the Item in warehouse
	 * @param price the price of the Item in warehouse
	 * @param quantity the quantity of the Item in warehouse
	 */
	public Item (String id, String price, String quantity){
		try{
			itemID=id;
			double itemPrice=Double.parseDouble(price);
			this.price=itemPrice;
			this.quantity=Integer.parseInt(quantity);		
			//calls init method to perform some checking
			init();
		}
		catch (NumberFormatException nfe){
			System.out.println("ItemID: "+itemID+ " (wrong input in price or quantity).");
			itemID="Wrong";
		}

	}	
	
	public Item(){
		
	}

	/**
	 * initializes the constructor parameters, checking for inappropriate input 
	 * and if finds it so, changes the Item ID to "Wrong" so that we can later
	 * locate the wrong item. 
	 * Additionally, it catches a potential NmberFormatException in case
	 * the item id is not an arithmetic value
	 */
	public void init() {

		try{
			//check if the item id is between [0-999]
			if ( itemID.length() < 0 || Integer.parseInt(itemID) < MINIMUM_ITEM_ID || 
					Integer.parseInt(itemID) > MAXIMUM_ITEM_ID ) {

				System.out.println("Out of range Item ID. ("+itemID+")");
				itemID="Wrong";
			}
			
			//check if the item id is empty field
			if ( itemID.isEmpty() || itemID.equals("") ) {

				System.out.println("Error in Item List: An Item ID field is empty.");
				itemID="Wrong";
			}
			
			//check if the price is negative
			if ( price <= MINIMUM_PRICE ){

				System.out.println("Item Id: "+itemID+" Error in Item List (Negative price) ");
				itemID="Wrong";
			}
			
			//check if the quantity is negative
			if ( quantity <= MINIMUM_QUANTITY ){

				System.out.println("Item Id: "+itemID+"Error in Item List (Negative quantity) ");
				itemID="Wrong";
			}
		}
		catch (NumberFormatException nfe){
			System.out.println("Wrong ID input in Item List: "+itemID);
			itemID="Wrong";
		}
	}

	// some get and set functions
	public String getItemID() {
		return itemID;
	}
	
	public void setItemID(String itemID) {
		this.itemID = itemID;
	}
	
	public double getPrice() {
		return price;
	}
	
	public void setPrice(double price) {
		this.price = price;
	}
	
	public int getQuantity() {
		return quantity;
	}
	
	public synchronized void setQuantity(int quantity) {
		this.quantity = quantity;
	}

	/* Overrides toString() method 
	 * @return String sequence
	 */
	public String toString() {
		return ""+ quantity ;
	}

	/** Overrides equals() method and check whether the parameter instance is one of 
	 *  Item and returns if its ID is equal to the another Items.
	 * @param Object an Item object
	 * return true or false
	 **/
	public boolean equals(Object other)
	{
		if(other instanceof Item) {
			Item otherItem = (Item) other;
			return itemID.equals(otherItem.getItemID());
		}
		else {
			return false;
		}
	}

	/** Overrides  compareTo() method and compares an ID to another one
	 * @param Item an Item object
	 * @return a negative integer if this id comes before the parameter's id,
	 *         zero if they are equal and a positive integer if this
	 *         comes after the other.
	 **/
	public int compareTo(Item other){
		return itemID.compareTo(other.getItemID());
	}
	// methods to register, remove and notify observers
	 public void registerObserver(Observer obs) {
	  registeredObservers.add(obs);
	 }

	 public void removeObserver(Observer obs) {
	  registeredObservers.remove(obs);
	 }

	 public void notifyObservers() {
	  for (Observer obs : registeredObservers)
	   obs.update();
	 }
}


